//! Cranelift JIT 编译器实现
//! 
//! 为Pipit字节码提供高性能的即时编译支持，将寄存器式字节码


pub mod optimizer;
pub mod integration;
pub mod precompiler;
pub mod config;

use std::collections::HashMap;
use std::time::{Duration, Instant};

mod bytecode_compiler;
pub use bytecode_compiler::{BytecodeCompiler, CompilationError, execute_compiled_function};
pub use precompiler::Precompiler;
pub use config::{PrecompileConfig, OptimizationLevel, CacheStrategy, ModuleConfig};

/// JIT编译器优化级别（内部使用）
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum JITOptimizationLevel {
    None,
    Basic,
    Aggressive,
}

/// JIT编译器主结构
pub struct PipitJIT {
    compiled_functions: HashMap<String, *const u8>,
    stats: JITStats,
    optimization_level: JITOptimizationLevel,
    precompiled_modules: HashMap<String, Vec<u8>>, // 预编译模块缓存
}

impl PipitJIT {
    /// 创建新的JIT编译器
    pub fn new(optimization_level: JITOptimizationLevel) -> Self {
        Self {
            compiled_functions: HashMap::new(),
            stats: JITStats::new(optimization_level),
            optimization_level,
            precompiled_modules: HashMap::new(),
        }
    }

    /// 编译函数到机器码
    pub fn compile_function(&mut self, name: &str, bytecode: &[u8]) -> Result<*const u8, CompilationError> {
        let start = Instant::now();
        
        let mut compiler = BytecodeCompiler::new(self.optimization_level)?;
        let func_ptr = compiler.compile_function(name, bytecode)?;
        
        self.compiled_functions.insert(name.to_string(), func_ptr);
        self.stats.record_compilation(name, start.elapsed());
        
        Ok(func_ptr)
    }

    /// 预编译模块（在编译阶段完成JIT编译）
    pub fn precompile_module(&mut self, module_name: &str, bytecode: &[u8]) -> Result<(), CompilationError> {
        let start = Instant::now();
        
        // 预编译整个模块
        let mut compiler = BytecodeCompiler::new(self.optimization_level)?;
        let func_ptr = compiler.compile_function(module_name, bytecode)?;
        
        // 缓存预编译结果
        self.compiled_functions.insert(module_name.to_string(), func_ptr);
        self.precompiled_modules.insert(module_name.to_string(), bytecode.to_vec());
        self.stats.record_precompilation(module_name, start.elapsed());
        
        Ok(())
    }

    /// 获取编译后的函数指针
    pub fn get_function(&self, name: &str) -> Option<*const u8> {
        self.compiled_functions.get(name).copied()
    }

    /// 获取预编译的模块
    pub fn get_precompiled_module(&self, module_name: &str) -> Option<&Vec<u8>> {
        self.precompiled_modules.get(module_name)
    }

    /// 获取编译的函数数量
    pub fn compiled_count(&self) -> usize {
        self.compiled_functions.len()
    }

    /// 获取统计信息
    pub fn get_stats(&self) -> &JITStats {
        &self.stats
    }

    /// 检查函数是否已编译
    pub fn is_compiled(&self, name: &str) -> bool {
        self.compiled_functions.contains_key(name)
    }

    /// 检查模块是否已预编译
    pub fn is_module_precompiled(&self, module_name: &str) -> bool {
        self.precompiled_modules.contains_key(module_name)
    }
}

/// JIT统计信息
#[derive(Debug)]
pub struct JITStats {
    pub total_functions: usize,
    pub optimization_level: JITOptimizationLevel,
    pub total_compilation_time: Duration,
    pub precompiled_functions: usize,
    pub precompilation_time: Duration,
}

impl JITStats {
    pub fn new(level: JITOptimizationLevel) -> Self {
        Self {
            total_functions: 0,
            optimization_level: level,
            total_compilation_time: Duration::new(0, 0),
            precompiled_functions: 0,
            precompilation_time: Duration::new(0, 0),
        }
    }

    pub fn record_compilation(&mut self, _name: &str, duration: Duration) {
        self.total_functions += 1;
        self.total_compilation_time += duration;
    }

    pub fn record_precompilation(&mut self, _name: &str, duration: Duration) {
        self.precompiled_functions += 1;
        self.precompilation_time += duration;
    }
}

impl From<config::OptimizationLevel> for JITOptimizationLevel {
    fn from(level: config::OptimizationLevel) -> Self {
        match level {
            config::OptimizationLevel::None => JITOptimizationLevel::None,
            config::OptimizationLevel::Basic => JITOptimizationLevel::Basic,
            config::OptimizationLevel::Advanced => JITOptimizationLevel::Aggressive,
            config::OptimizationLevel::Maximum => JITOptimizationLevel::Aggressive,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_basic_jit_compilation() {
        let mut jit = PipitJIT::new(JITOptimizationLevel::Basic);
        let bytecode = vec![0x01, 0x02, 0x03];
        
        let result = jit.compile_function("test_func", &bytecode);
        assert!(result.is_ok());
        assert!(jit.is_compiled("test_func"));
        assert_eq!(jit.compiled_count(), 1);
    }

    #[test]
    fn test_optimization_levels() {
        let jit = PipitJIT::new(JITOptimizationLevel::None);
        assert_eq!(jit.get_stats().optimization_level, JITOptimizationLevel::None);
        
        let jit2 = PipitJIT::new(JITOptimizationLevel::Aggressive);
        assert_eq!(jit2.get_stats().optimization_level, JITOptimizationLevel::Aggressive);
    }
}